package pyip.lib.javalearn.thread.interrupt;

import java.util.Random;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 测试 Thread.stop()方法.<br>
 * 我们会发现使用stop来终止一个线程是不讲道理、极其残暴的，不论目标线程在执行任何语句，一律强行终止线程，最终将导致一些残缺的对象和不可预期的问题产生。<br>
 * <br>
 * <b>sample:</b><br>
 * t1#stop(); 会导致线程 t1正在执行的那一行代码报错(ThreadDeath, 继承与Error),<br>
 * 如果线程 t1当前正持有锁, 被stop()之后 t1会释放该锁, 如果该Error没有被捕获并处理, 会影响代码执行逻辑(如造成对象状态不一致). <br>
 * <br>
 * 谁也不知道Error会在哪条语句抛出, 假如对象状态之间的关系很复杂, 这种方式几乎是无法维护的, 太复杂了! 正是因为可能导致对象状态不一致, stop才被禁用.<br>
 * <br>
 * 如果是中断操作，它决计不会在执行int赋值的时候抛出错误，这样程序对于对象状态一致性就是可控的。 <br>
 * <br>
 * <b>t1#stop(new Exception("stop t1")) 和 t1#stop()的区别</b><br>
 * 被终止的线程没有任何异常抛出，在线程终止后找不到任何被终止时执行的代码行，或者是堆栈信息（仅仅是main线程执行stop语句的异常而已，并非被终止的线程）。
 * @author yepeng
 * @date 2015年4月22日
 */
public class ThreadStopDemo {
    private static final Logger logger = LoggerFactory.getLogger(ThreadStopDemo.class);

    private static final int[] array = new int[80000];
    private static final Thread t1 = new Thread() {
        public void run() {
            try {
                sort(array);
                logger.debug("t1, sort successful");
            } catch (Error err) {
                // 如果不捕获Error, 那么线程将直接结束, 且JVM 似乎 也不会报错
                logger.error("t1, err instanceof ThreadDeath: " + (err instanceof ThreadDeath), err);
            }
            logger.debug("t1 exit");
        }
    };

    static {
        Random random = new Random();
        for (int i = 0; i < array.length; i++) {
            array[i] = random.nextInt(i + 1);
        }
    }

    private static int sort(int[] array) {
        for (int i = 0; i < array.length - 1; i++) {
            for (int j = 0; j < array.length - i - 1; j++) {
                if (array[j] < array[j + 1]) {
                    int temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
            }
        }
        return array[0];
    }

    @SuppressWarnings("deprecation")
    public static void main(String[] args) throws Exception {
        logger.debug("main start");
        t1.start();
        TimeUnit.SECONDS.sleep(1);

        logger.debug("main goto stop thread t1");

        // 调用#stop() t1当前代码行会抛出 ThreadDeath错误
        // t1.stop();

        // 调用#stop(Exception) t1将不会抛出错误, 而是直接结束, 只是主线程会报错
        // 被终止的线程没有任何异常抛出，你在线程终止后找不到任何被终止时执行的代码行，或者是堆栈信息（打印的异常仅仅是main线程执行stop语句的异常而已，并非被终止的线程）。
        t1.stop(new Exception("stop t1"));

        logger.debug("main exit");
    }
}
